/*
*NPC有三种可能
1.NPC=PC+4  常规指令
2。NPC = PC+offset  B型指令且发生跳转，以及jal指令
3. NPC = register+offset即NPC = ALU.C  jalr指令
*/
`include "param.v"  


module NPC (
    input wire [31:0] pc,//上一个PC，用于计算PC+4
    input wire [31:0] offset,// 立即数扩展后的偏移量，用于计算pc+offset
    input wire [31:0] ALU_C,//连接ALU.C
    input wire [1:0] ALU_f,//连接ALU.f，用于判断比较结果是大于小于等于  00ge,01:lt,10:eq,11:invalid
    input wire [2:0] npc_op,//连接控制器，用于判断是哪种分支，和br信号配合使用,
    output reg [31:0] pc4,
    output reg [31:0] npc
);

//定义npc_op的信号值
parameter  NPC_PC4 =3'b000;
parameter  NPC_BEQ =3'b001;
parameter  NPC_BNE =3'b010;
parameter  NPC_BLT =3'b011;
parameter  NPC_BGE =3'b100;
parameter  NPC_JAL =3'b101;
parameter  NPC_JALR =3'b110;

//定义ALU.f的信号值
parameter GT = 2'b00;
parameter LT = 2'b01;
parameter EQ = 2'b10;
parameter INVALID = 2'b11;

always @(*) begin
    pc4 = pc+'b100;//pc4永远是pc+4,这个输出仅在jal和 jalr指令中，存储pc+4到rd中的时候用到
    if(npc_op==NPC_PC4)begin
        npc = pc+4;
    end
    //4种不同的branch
    else if(npc_op==NPC_BGE && (ALU_f==GT || ALU_f== EQ))begin
        npc = pc + offset;
    end
    else if(npc_op==NPC_BEQ && ALU_f==EQ)begin
        npc = pc + offset;
    end
    else if(npc_op==NPC_BNE && ALU_f != EQ)begin
        npc = pc + offset;
    end
    else if(npc_op==NPC_BLT && ALU_f==LT)begin
        npc = pc + offset;
    end
    //jalr
    else if(npc_op==NPC_JALR)begin
        npc = ALU_C;
    end
    //jal
    else if(npc_op==NPC_JAL)begin
        npc = pc + offset;
    end
    else begin npc = pc + 32'h4; end
    
end

    
endmodule